﻿using System.Data;

namespace TPXSDK.NET.Log;

/// <summary>
/// 通用日志对象【日志文件，自带格式描述】
/// </summary>
public class LogEntryComm
{
    public required string Name { get; set; }
    public required byte[] Format { get; set; }
    public required string[] Member { get; set; }
    public DataTable? Data { get; set; }

    private void GenRowData(byte[] entryData, DataRow dr)
    {
        var offset = 0;
        var i = 0;
        foreach (var c in Format)
        {
            if (c == 'b') dr[i] = (sbyte)entryData[offset++];
            if (c == 'B') dr[i] = entryData[offset++];
            if (c == 'h')
            {
                dr[i] = BitConverter.ToInt16(entryData, offset);
                offset += 2;
            }

            if (c == 'H')
            {
                dr[i] = BitConverter.ToUInt16(entryData, offset);
                offset += 2;
            }

            if (c == 'i')
            {
                dr[i] = BitConverter.ToInt32(entryData, offset);
                offset += 4;
            }

            if (c == 'I')
            {
                dr[i] = BitConverter.ToUInt32(entryData, offset);
                offset += 4;
            }

            if (c == 'f')
            {
                dr[i] = BitConverter.ToSingle(entryData, offset);
                offset += 4;
            }

            if (c == 'd')
            {
                dr[i] = BitConverter.ToDouble(entryData, offset);
                offset += 8;
            }

            if (c == 'q')
            {
                dr[i] = BitConverter.ToInt64(entryData, offset);
                offset += 8;
            }

            if (c == 'Q')
            {
                dr[i] = BitConverter.ToUInt64(entryData, offset);
                offset += 8;
            }

            i++;
        }
    }

    internal void AddData(byte[] data)
    {
        if (null == data || data.Length != Length) return;
        if (null == Data)
        {
            Data = new DataTable();
            for (var i = 0; i < Member.Length; i++)
            {
                var col = Data.Columns.Add(Member[i]);
                col.DataType = GetDataType(Format[i]);
            }
        }

        var dr = Data.NewRow();
        GenRowData(data, dr);
        Data.Rows.Add(dr);
    }

    #region 数据类型编码
    /*
      b   : int8_t
      B   : uint8_t
      h   : int16_t
      H   : uint16_t
      i   : int32_t
      I   : uint32_t
      f   : float
      d   : double
      q   : int64_t
      Q   : uint64_t
     */
    public int Length
    {
        get
        {
            var len = 0;
            foreach (var c in Format)
            {
                if (c == 'b' || c == 'B') len += 1;
                if (c == 'h' || c == 'H') len += 2;
                if (c == 'i' || c == 'I' || c == 'f') len += 4;
                if (c == 'd' || c == 'q' || c == 'Q') len += 8;
            }
            return len;
        }
    }
    private static Type? GetDataType(byte c)
    {
        if (c == 'b') return typeof(sbyte);
        if (c == 'B') return typeof(byte);
        if (c == 'h') return typeof(short);
        if (c == 'H') return typeof(ushort);
        if (c == 'i') return typeof(int);
        if (c == 'I') return typeof(uint);
        if (c == 'f') return typeof(float);
        if (c == 'd') return typeof(double);
        if (c == 'q') return typeof(long);
        if (c == 'Q') return typeof(ulong);
        return null;
    }
    #endregion
}
